package com.barunlab.ems.server.push;

import java.util.Hashtable;
import java.util.Iterator;

import org.apache.log4j.Logger;

import com.barunlab.ems.constants.EmsEventType;
import com.barunlab.ems.model.EmsEvent;
import com.barunlab.ems.rmi.ClientInterface;
import com.barunlab.ems.server.main.ServerProperties;

/**
 * ClientSession을 관리하는 클래스
 * 
 * @author 배수현
 * @version SKT SI R1.0
 * @since JDK6.0
 * @created 2013
 */
public class ClientSessionManager {
	private static Logger LOGGER = Logger.getLogger(ClientSessionManager.class);
	
	private class SessionCheckThread extends Thread {
		private EmsEvent pingEvent;
		
		public SessionCheckThread() {
			pingEvent = new EmsEvent(EmsEventType.HEARTBEAT);
		}
		
		@Override
		public void run() {
			while ( true ) {
				try {
					Iterator<String> keyIter = clientRepo.keySet().iterator();
					while ( keyIter.hasNext() ) {
						String key = keyIter.next();
						ClientSession clientSession = clientRepo.get(key);
						clientSession.push(pingEvent);
					}
				}
				catch ( Exception ex ) {
					LOGGER.error(ex.getMessage(), ex);
				}
				
				try {
					Thread.sleep(ServerProperties.CLIENT_HEARTBEAT_DURATION);
				}
				catch ( Exception ex ) {
					LOGGER.error(ex.getMessage(), ex);
				}
			}
		}
	}
	
	private static Hashtable<String, ClientSession> clientRepo = new Hashtable<String, ClientSession>();
	
	/**
	 * 클라이언트 세션 체크를 시작한다.
	 */
	public void startClientCheck() {
		SessionCheckThread thread = new SessionCheckThread();
		thread.start();
	}
	
	/**
	 * 클라이언트 세션을 추가한다.
	 * 
	 * @param userName
	 * @param clientInterface
	 */
	public static void registerClient(String userName, ClientInterface clientInterface) {
		LOGGER.debug(String.format("registerClient(%s)", userName));
		
		ClientSession newSession = new ClientSession(userName, clientInterface);
		newSession.start();
		
		clientRepo.put(userName, newSession);
	}
	
	/**
	 * 클라이언트 세션을 종료한다.
	 * 
	 * @param userName
	 */
	public static void unregisterClient(String userName) {
		LOGGER.debug(String.format("unregisterClient(%s)", userName));
		
		ClientSession session = clientRepo.remove(userName);
		if ( session != null ) {
			session.close();
		}
	}
	
	/**
	 * 클라이언트 세션을 강제 종료한다.
	 * 
	 * @param terminator
	 * @param userName
	 */
	public static void terminateClient(String terminator, String userName) {
		LOGGER.debug(String.format("terminateClient(%s, %s)", terminator, userName));
		
		ClientSession clientSession = clientRepo.get(userName);
		if ( clientSession != null ) {
			Object[] params = new Object[1];
			params[0] = terminator;
			
			EmsEvent event = new EmsEvent(EmsEventType.TERMINATE, params);

			clientSession.push(event);
		}		
	}
	
	/**
	 * 명령어 처리 결과를 클라이언트에 전송한다.
	 * 
	 * @param clientInfo
	 * @param commandInfo
	 */
	/*
	public static void cmdResponse(ClientInfo clientInfo, CommandInfo commandInfo) {
		LOGGER.debug(String.format("cmdResponse(%s)\n", clientInfo.getName()));
		
		ClientSession clientSession = clientRepo.get(clientInfo.getName());
		if ( clientSession != null ) {
			Object[] eventParams = new Object[2];
			eventParams[0] = clientInfo;
			eventParams[1] = commandInfo;

			EmsEvent hmiEvent = new EmsEvent(HmiEventType.CMD_RESPONSE, eventParams);

			clientSession.push(hmiEvent);
		}
		else {
			System.out.println(String.format("Client Session(%s) doesn't exist.", clientInfo.getUserName()));	
		}
	}
	*/
}
